package com.bjsxt;
/*synchronized 是放在线程中，还是其它类中的方法，取决于设计*/
//使用Class作为线程对象锁
// 在不同线程中，拥有相同Class对象中的synchronized 会互斥
/*    synchronized(xx.class){ 同步代码 }
或 加到静态方法上：synchronized public static void accessVal(){}
静态方法上的对象锁是以静态方法上的类为对象锁
 */

//使用自定义对象作为线程对象锁
//在不同线程中，拥有相同自定义对象中的synchronized 会互斥
// 语法结构：synchronized(自定义对象){ 同步代码 }

//定义销售部员工
class Sale{
    private String name;
    public Sale(String name){
        this.name=name;
    }
    public void money(){
        //这里的锁对象不可以this ，因为this是相同对象才互斥。
        //现在是不同对象
        synchronized (Sale.class) {
            try {
                System.out.println(this.name + "被领导表扬");
                Thread.sleep(500);
                System.out.println(this.name + "拿钱");
                Thread.sleep(500);
                System.out.println(this.name + "对公司表示感谢");
                Thread.sleep(500);
                System.out.println(this.name + "开开心心拿钱走人");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
/*定义程序员类*/
class Programmer03{
    private String name;
    public Programmer03(String name){
        this.name=name;
    }
    //打开电脑
    public void computer(){
        //放在方法中
        // public synchronized void computer(){
        //synchronized public void computer(){
        synchronized (this) {
            try {
                System.out.println(this.name + "接通电源");
                Thread.sleep(500);
                System.out.println(this.name + "按下开机键");
                Thread.sleep(500);
                System.out.println(this.name + "系统启动中");
                Thread.sleep(500);
                System.out.println(this.name + "系统启动成功");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //编码
    public void coding(){
        synchronized (this) {
            try {
                System.out.println(this.name + "双击IDEA");
                Thread.sleep(500);
                System.out.println(this.name + "Idea启动完毕");
                Thread.sleep(500);
                System.out.println(this.name + "写代码");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //去卫生间
    public void wc(){
        //让所有线程都有互斥关系，字符串写什么都可以  并行改为串行
        synchronized ("s") {
            try {
                System.out.println(this.name + "打开卫生间门");
                Thread.sleep(500);
                System.out.println(this.name + "开始排泄");
                Thread.sleep(500);
                System.out.println(this.name + "冲水");
                Thread.sleep(500);
                System.out.println(this.name + "离开卫生间");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //领取奖金
    //静态的synchronized
   /* synchronized public static void money(){
         try {
             //静态方法不可以  用this.name
                System.out.println(Thread.currentThread().getName() + "被领导表扬");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName() + "拿钱");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName() + "对公司表示感谢");
                Thread.sleep(500);
                System.out.println(Thread.currentThread().getName() + "开开心心拿钱走人");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    }*/
    public void money(){
        //这里的锁对象不可以this ，因为this是相同对象才互斥。
        //现在是不同对象
        synchronized (Programmer03.class) {
            try {
                System.out.println(this.name + "被领导表扬");
                Thread.sleep(500);
                System.out.println(this.name + "拿钱");
                Thread.sleep(500);
                System.out.println(this.name + "对公司表示感谢");
                Thread.sleep(500);
                System.out.println(this.name + "开开心心拿钱走人");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
class Manager{
    private String name;
    public Manager(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }
//敬酒
 //可能会有很多经理
 //传过来的经理，员工
 public void cheers(String mName,String eName){
     //锁对象可以用this 因为同一个对象经理
    // synchronized (this)
     try {
         System.out.println(mName + "来到"+eName+"面前");
         Thread.sleep(500);
         System.out.println(eName + "拿起洒杯");
         Thread.sleep(500);
         System.out.println(mName + "和"+eName+"干杯");

     } catch (InterruptedException e) {
         e.printStackTrace();
     }
 }
}
//打开电脑的工作线程
class Working05 extends Thread{
    private Programmer02 p;
    public Working05(Programmer02 p){
        this.p=p;
    }
    @Override
    public void run() {
        this.p.computer();
    }
}
//编写代码的线程
class Working06 extends Thread{
    private Programmer02 p;
    public Working06(Programmer02 p){
        this.p=p;
    }
    @Override
    public void run() {
        this.p.coding();
    }
}
//卫生间线程
class Wc01 extends Thread{
    private Programmer02 p;
    public Wc01(Programmer02 p){
        this.p=p;
    }
    @Override
    public void run() {
        this.p.wc();
    }
}
// 领奖金
class ProgrammerMoney extends Thread{
    private Programmer03 p;
    public ProgrammerMoney(Programmer03 p){
        this.p=p;
    }

    @Override
    public void run() {
        this.p.money();
    }
}
//销售部线程
class SaleMoney extends Thread{
    private Sale s;
    public SaleMoney(Sale s){
        this.s=s;
    }
    @Override
    public void run() {
        this.s.money();
    }
}
//敬酒线程
class CheersThread extends Thread{
    private Manager manager;//经理
    private String name;//员工
    public CheersThread(Manager manager,String name){
        this.manager=manager;
        this.name=name;
    }
    @Override
    public void run() {
        //这里不可以用this,因为这里可能有多个员工启动多个线程，变成不同的对象
        //自定义对象，指定锁对象
        synchronized (this.manager) {
            //在线程调用经理类中的方法
            this.manager.cheers(this.manager.getName(), name);
        }
    }
}
public class TestClassSynchronized {
    public static void main(String[] args) {
       /* Programmer03 p = new Programmer03("小明");
        Programmer03 p1 = new Programmer03("小张");
        new ProgrammerMoney(p).start();
        new ProgrammerMoney(p1).start();
        Sale s = new Sale("小红");
        Sale s1 = new Sale("小丽");
        new SaleMoney(s).start();
        new SaleMoney(s1).start();*/
        Manager manager = new Manager("张三丰");
        new CheersThread(manager,"张三").start();
        new CheersThread(manager,"李四").start();
    }
}
